import React from 'react'
import moment from 'moment';
import {
  Table, Input, Button, Popconfirm, Form, InputNumber, DatePicker, Checkbox, Select
} from 'antd';

import EditableContext from './EditableContext'
import styles from './index.less'
const FormItem = Form.Item;
const Option = Select.Option;

class EditableCell extends React.Component {
  state = {
    editing: false,
  }

  defaultDatePattern = 'YYYY-MM-DD HH:mm:ss';

  componentDidMount() {
    if (this.props.editable) {
      document.addEventListener('click', this.handleClickOutside, true);
    }
  }

  componentWillUnmount() {
    if (this.props.editable) {
      document.removeEventListener('click', this.handleClickOutside, true);
    }
  }

  toggleEdit = () => {
    const editing = !this.state.editing;
    this.setState({ editing }, () => {
      if (editing && this.input) {
        this.input.focus();
      }
    });
  }

  handleClickOutside = (e) => {
    const { editing } = this.state;
    if (editing && this.cell !== e.target && !this.cell.contains(e.target)) {
      this.delaySave();
    }
  }

  /**
   * 保存单元格数据
   */
  save = () => {
    const { record, handleSave, dataIndex, inputType, datePattern=this.defaultDatePattern } = this.props;
    this.form.validateFields((error, values) => {
      if (error) {
        return;
      }
      const value = values[dataIndex];
      if(inputType === 'date' ){
        values[dataIndex] = value.format(datePattern);
      }
      if (inputType === 'checkbox') {
        values[dataIndex] = value ? '1' : '0';
      }
      // 改变单元格编辑状态
      this.toggleEdit();
      // 编辑表格保存数据的回调
      handleSave({ ...record, ...values });
    });
  }

  /**
   * 延迟保存，如CheckBox, DatePicker onChange时，调用save时form获取到的值还是修改前的
   */
  delaySave = ()=>{
    setTimeout(()=>{this.save()}, 100);
  }

  /**
   * 单元格编辑状态
   * @returns {*}
   */
  renderCellEditing = ()=>{
    const { inputType, record, dataIndex, selectProps } = this.props;
    if (inputType === 'number') {
      return <InputNumber ref={node => (this.input = node)} onPressEnter={this.delaySave} />;
    } else if(inputType === 'date' ){
      return <DatePicker ref={node => (this.input = node)} onChange={()=>this.delaySave} />
    } else if(inputType === 'checkbox' ){
      return <Checkbox checked={record[dataIndex] == '1'} onChange={this.delaySave} />
    } else if(inputType === 'select' ){
      const { dataSource, valueKey, textKey } = selectProps;
      return (<Select>
        {dataSource.map(item => (
          <Option key={item[valueKey]} value={item[valueKey]}>
            {item[textKey]}
          </Option>
        ))}
      </Select>);
    }
    return <Input ref={node => (this.input = node)} onPressEnter={this.delaySave} />;
  }

  /**
   * 设置默认值
   * @returns {*}
   */
  getInputDefauleValue = ()=>{
    const { dataIndex, record, inputType } = this.props;
    const value = record[dataIndex];
    if (inputType === 'date') {
      return moment(value);
    }
    if (inputType === 'checkbox') {
      return value == '1';
    }
    return record[dataIndex];
  }

  /**
   * 处理非编辑状态下显示的值
   * @returns {string}
   */
  renderCellDisplay = ()=>{
    const { children, inputType, record, dataIndex, render } = this.props;
    if(record){
      const value = record[dataIndex];
      if(render && typeof render === "function"){
        return render(value, record);
      }
    }
    return children;
  }

  render() {
    const { editing } = this.state;
    const {
      editable,
      dataIndex,
      title,
      render,
      record,
      index,
      handleSave,
      inputType,
      datePattern,
      selectProps,
      ...restProps
    } = this.props;
    return (
      <td ref={node => (this.cell = node)} {...restProps}>
        {editable ? (
          <EditableContext.Consumer>
            {(form) => {
              this.form = form;
              return (
                editing ? (
                  <FormItem style={{ margin: 0 }}>
                    {form.getFieldDecorator(dataIndex, {
                      rules: [{
                        required: true,
                        message: `${title} is required.`,
                      }],
                      initialValue: this.getInputDefauleValue(),
                    })(
                      this.renderCellEditing()
                    )}
                  </FormItem>
                ) : (
                  <div
                    className={styles["editable-cell-value-wrap"]}
                    style={{ paddingRight: 24 }}
                    onClick={this.toggleEdit}
                  >
                    { this.renderCellDisplay() }
                  </div>
                )
              );
            }}
          </EditableContext.Consumer>
        ) : this.renderCellDisplay() }
      </td>
    );
  }
}

export default  EditableCell;
